#!/usr/bin/env python
# -*- coding: utf-8 -*-

# Reference: https://github.com/sigwo/ip-subnet-calc/blob/master/ip-subnet-calc.py
# v02.11 BETA
#
# by Steven Grove (@sigwo)
#           www.sigwo.com
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
# Date: 09-01-13
#
# Changed by: Bruno Alves, n.º 6152; Neuza Figueira, n.º 6036
# 11-03-2014

import sys
import os
import string

def ip_subnet_calc(xaddr, xcidr):
	'''Method to calcule the IP of a network given an host address and the network mask.
	   @param xaddr -> Host IP address.
	   @return xcidr -> Network mask in CIDR notation (no /).'''
	# Get address string and CIDR string from command line
	#xaddr = raw_input("IP address: ") # need to validate input of IP address 
	#xcidr = raw_input("CIDR notation, NO / mark!: ")
	addr = xaddr.split('.')
	cidr = int(xcidr)

	# Initialize the netmask and calculate based on CIDR mask
	mask = [0, 0, 0, 0]
	for i in range(cidr):
	    mask[i/8] = mask[i/8] + (1 << (7 - i % 8)) 

	# Initialize net and binary and netmask (net) with addr to get network
	net = []
	for i in range(4):
	    net.append(int(addr[i]) & mask[i])

	# Duplicate net into broad array, gather host bits, and generate broadcast
	broad = list(net)
	brange = 32 - cidr
	for i in range(brange):
	    broad[3 - i/8] = broad[3 - i/8] + (1 << (i % 8))

	# This gives you usable hosts for the given subnet
	xhost = 2 ** brange - 2
	host = "{:,}".format(xhost)

	# Initialize o for wildcard mask (imask) with broadcast - net 
	o = [0, 0, 0, 0]
	for i in range(4):
		o[i] = broad[i] - net[i]

	# This gives the wildcard mask for the given subnet	
	imask = []
	for i in range (4):
		imask.append(int(o[i]) & broad[i])

	fNetwork = ".".join(map(str, net))
	fNetwork = fNetwork + "/" + str(xcidr)
	return fNetwork
